/**
 * 表格选择器
 * 场景：账户管理-角色管理-数据权限
 *
 * @author wujianx
 * @createDate 2020-11-7
 * @editor Elsa Wang
 * @editDate 2021-06-28
 */
import Checkbox from 'antd/es/checkbox';
import { CheckboxChangeEvent } from 'antd/lib/checkbox';
import React from 'react';
import './style.scss';

/**
 * 单项权限
 */
export interface CheckPermissionItem {
  caption: string;
  key: string | number;
  checked: boolean;
  disabled: boolean;
  children?: CheckPermissionItem[];
}

/**
 * CheckTable入参
 */
export interface CheckTableProps {
  option: {
    caption: string;
    key: string | number;
    checked: boolean;
    disabled: boolean;
    children?: CheckPermissionItem[];
  };
  tableHeader1?: string;
  tableHeader2?: string;
}

/**
 * CheckTable维护的state
 */
interface CheckTableState extends CheckTableProps {
  values: (number | string)[];
}

/**
 * 三层勾选控件
 * 场景：
 * 角色管理-功能权限中，会使用此控件来对三级权限进行勾选操作
 */
export class CheckTable extends React.Component<CheckTableProps, CheckTableState> {
  constructor(prop: CheckTableProps) {
    super(prop);
    this.state = {
      ...prop,
      values: [],
    };
  }

  public getValue(): (string | number)[] {
    const { option } = this.state;
    const values = [];
    option.checked && values.push(option.key);
    option.children?.forEach(son => {
      son.checked && values.push(son.key);
      son.children?.forEach(child => {
        child.checked && values.push(child.key);
      });
    });
    this.setState({
      values: values,
    });
    return values;
  }

  /**
   * 统一处理控件内的checkbox的change事件
   */
  private onChange(e: CheckboxChangeEvent, item: CheckPermissionItem) {
    const checked = e.target.checked;
    let option = this.state.option;
    const level = this.findLevel(item);
    if (level === 1) {
      // 一级菜单
      !option.disabled && (option.checked = checked);
      item.children?.forEach(item => {
        !item.disabled && (item.checked = checked);
        const children = item.children;
        children?.forEach(son => {
          !son.disabled && (son.checked = checked);
        });
      });
      option = item as any;
    }
    if (level === 2) {
      // 二级菜单
      !item.disabled && (item.checked = checked);
      checked && (option.checked = checked);
      const target = option.children?.find(child => child.key === item.key) as CheckPermissionItem;
      target.children?.forEach(item => {
        !item.disabled && (item.checked = checked);
      });
    }
    if (level === 3) {
      // 三级：操作
      option.children?.forEach(son => {
        son.children?.forEach(child => {
          if (child.key === item.key) {
            if (!item.disabled) {
              child.checked = checked;
              checked && (son.checked = checked);
              checked && (option.checked = checked);
            }
          }
        });
      });
    }
    this.setState(
      {
        option: option,
      },
      () => {
        this.getValue();
        this.forceUpdate();
      }
    );
  }

  /**
   * 寻找一个item的所在层级
   */
  private findLevel(item: CheckPermissionItem): 1 | 2 | 3 {
    const { key } = item;
    const { option } = this.state;
    const subMenu = option.children;
    if (key === option.key) {
      return 1;
    } else if (subMenu?.find(menu => key === menu.key)) {
      return 2;
    } else {
      return 3;
    }
  }

  render() {
    const { option, tableHeader1, tableHeader2 } = this.state;
    const submenus = option.children;

    return (
      <div className="check-table">
        <div className="checktable-title-room">
          <Checkbox
            disabled={option.disabled}
            checked={option.checked}
            onChange={e => {
              this.onChange(e, option as CheckPermissionItem);
            }}
          >
            {option.caption}
          </Checkbox>
        </div>
        {submenus && (
          <div className="checktable-table">
            {/* 1.有二级菜单和操作权限配置 */}
            {tableHeader2 && (
              <>
                <div className="checktable-table-col1 checktable-header">{tableHeader1}</div>
                <div className="checktable-table-col2 checktable-header">{tableHeader2}</div>
                {submenus.map((item, index) => {
                  return (
                    <div className="checktable-row" key={index}>
                      <div className="checktable-table-col1">
                        {/* 二级菜单列 */}
                        <Checkbox
                          disabled={item.disabled}
                          checked={item.checked}
                          onChange={e => {
                            this.onChange(e, item as CheckPermissionItem);
                          }}
                        >
                          {item.caption}
                        </Checkbox>
                      </div>
                      <div className="checktable-table-col2">
                        {/* 操作列 */}
                        {item.children?.map(child => {
                          return (
                            <Checkbox
                              key={item.caption + '_' + child.caption}
                              disabled={child.disabled}
                              checked={child.checked}
                              onChange={e => {
                                this.onChange(e, child as CheckPermissionItem);
                              }}
                            >
                              {child.caption}
                            </Checkbox>
                          );
                        })}
                      </div>
                    </div>
                  );
                })}
              </>
            )}
            {!tableHeader2 && (
              <>
                {/* 2.只有一级菜单和操作权限配置 */}
                <div className="checktable-table-col0 checktable-header">{tableHeader1}</div>
                <div className="checktable-row">
                  {/* 仅包含一级菜单，显示操作列 */}
                  <div className="checktable-table-col0">
                    {submenus.map((item, index1) => {
                      return (
                        <Checkbox
                          key={index1}
                          disabled={item.disabled}
                          checked={item.checked}
                          onChange={e => {
                            this.onChange(e, item as CheckPermissionItem);
                          }}
                        >
                          {item.caption}
                        </Checkbox>
                      );
                    })}
                  </div>
                </div>
              </>
            )}
          </div>
        )}
      </div>
    );
  }
}

/**
 * CheckTable控件测试集
 */
export const CheckTableTest: React.FC = () => {
  function returnTrue() {
    return true;
  }

  const option = {
    caption: '账户管理',
    key: '8348',
    disabled: false,
    checked: returnTrue(),
    children: [
      {
        caption: '角色管理',
        key: '318',
        checked: true,
        disabled: false,
        children: [
          {
            caption: '新增',
            key: 32,
            disabled: false,
            checked: false,
          },
          {
            caption: '编辑',
            key: 321,
            disabled: false,
            checked: returnTrue(),
          },
        ],
      },
      {
        caption: '组织机构管理',
        key: '317',
        checked: true,
        disabled: false,
      },
    ],
  };

  return <CheckTable option={option} tableHeader1="二级菜单" tableHeader2="操作" />;
};
